#pragma once
#ifndef TCPSERVER_H
#define TCPSERVER_H
#include "EventLoop.h"
#include "TimeStamp.h"
#include "TcpConnection.h"
#include <functional>
#include "Acceptor.h"
#include "EventLoopThreadPool.h"
#include "InetAddress.h"
#include "NonCopyable.h"
#include "Callbacks.h"
#include <unordered_map>
#include "sys/socket.h"
#include <string>
namespace mymuduo {

// 对外服务器编程使用的类
class TcpServer : NonCopyable {
public:
    using ThreadInitCallback = std::function<void(EventLoop*)>;

    enum Option {
        kNoReusePort,
        kReusePort,
    };
    TcpServer(EventLoop *loop, const InetAddress &listenAddr, std::string name, Option option = kNoReusePort);
    ~TcpServer();

    void setThreadInitCallback(const ThreadInitCallback &cb) {threadInitCallback_ = cb;}
    void setConnectionCallback(const ConnectionCallback &cb) {connectionCallback_ = cb;}
    void setMessageCallback(const MessageCallback &cb) {messageCallback_ = cb;}
    void setWriteCompleteCallback(const WriteCompleteCallback &cb) {writeCompleteCallback_ = cb;}

    void setThreadNum(int numThreads); // 设置底层 subloop 个数
    void start(); // 开启服务器监听

private:
    using ConnectionMap = std::unordered_map<std::string, TcpConnectionPtr>;

    void newConnection(int socketfd, const InetAddress &peerAddr);
    void removeConnection(const TcpConnectionPtr &conn);
    void removeConnectionInLoop(const TcpConnectionPtr &conn);

    EventLoop *loop_; // baseloop，用户定义的 loop
    const std::string ipPort_;
    const std::string name_;
    std::unique_ptr<Acceptor> acceptor_; // 运行在 mainloop，监听新连接事件
    std::shared_ptr<EventLoopThreadPool> threadPool_;
    ConnectionCallback connectionCallback_; // 有新连接时的回调
    MessageCallback messageCallback_; // 有读写消息时的回调
    WriteCompleteCallback writeCompleteCallback_; // 消息发送完以后的回调
    ThreadInitCallback threadInitCallback_; // loop线程初始化以后的回调
    std::atomic_int started_;
    int nextConnId_;
    ConnectionMap connections_;
};

}

#endif